// 实现这个项目的构建任务

// 一、导入模块

const { series, parallel, src, dest, watch } = require('gulp')
// series()方法可按照传入的顺序依次执行Task
// parallel()方法按照并行的方式执行Task
// src() 创建读取流
// dest() 创建写入流
// watch() 自动监视文件路径的通配符，根据文件的变化决定是否执行某些任务

const cleanCss = require('gulp-clean-css')
// cleanCss() 压缩css代码的转换流

const rename = require('gulp-rename')
// rename() 修改别名

const fs = require('fs')
const { Transform } = require('stream')

//const sass = require('gulp-sass')
var sass = require('gulp-sass')(require('sass'));
// sass() 编译.scss

const babel = require('gulp-babel')
// js转换插件

const swig = require('gulp-swig')
// html转化插件

//const imagemin = require('gulp-imagemin')
// var  imagemin = require("gulp-imagemin"),
//      cache = require("gulp-cache");
// 图片转换插件

const del = require('del')

const browserSync = require('browser-sync')
const bs = browserSync.create()

const loadPlugins = require('gulp-load-plugins')
const plugins = loadPlugins()
// exports.foo = (done) => {
//   // 文件读取流
//   const read = fs.createReadStream('')
//   // 文件写入流
//   const write = fs.createWriteStream()
//   // 文件转换流
//   const transform = new Transform({
//     transform: (chunk, encoding, Callback) => {
//       // 核心转换过程实现
//       // chunk => 读取流中读取到的内容 (Buffer)
//       const input = chunk.toString()
//     }
//   })
// }

const data = {
  menus: [
    {
      name: 'Home',
      icon: 'aperture',
      link: 'index.html'
    },
    {
      name: 'Features',
      link: 'features.html'
    },
    {
      name: 'About',
      link: 'about.html'
    },
    {
      name: 'Contact',
      link: '#',
      children: [
        {
          name: 'Twitter',
          link: 'https://twitter.com/w_zce'
        },
        {
          name: 'About',
          link: 'https://weibo.com/zceme'
        },
        {
          name: 'divider'
        },
        {
          name: 'About',
          link: 'https://github.com/zce'
        }
      ]
    }
  ],
  pkg: require('./package.json'),
  date: new Date()
}

const clean = () => {
  return del(['dist','temp'])
}

// 样式编译
const style = () => {
  return src('src/assets/styles/*.scss',{ base: 'src'})  // 以src为基准保留原始结构
  .pipe(sass({ outputStyle: 'expanded'}))    // 输出样式的展开
  .pipe(dest('temp'))
  .pipe(bs.reload({ stream: true }))
}

// 脚本编译
const script = () => {
  return src('src/assets/scripts/*.js', { base: 'src'})
  .pipe(babel({presets: ['@babel/preset-env']}))
  .pipe(dest('temp'))
  .pipe(bs.reload({ stream: true }))
}

// 页面编译
const page = () => {
  return src('src/*.html', { base: 'src'})
  .pipe(swig({data}))
  .pipe(dest('temp'))
  .pipe(bs.reload({ stream: true }))
}

// 图片转换
const image = () => {
  return src('src/assets/images/**',{ base: 'src'})
  .pipe(imagemin())
  .pipe(dest('dist'))
}

// 文字转换
const font = () => {
  return src('src/assets/fonts/**',{ base: 'src'})
  .pipe(imagemin())
  .pipe(dest('dist'))
}

// 其他文件处理
const extra = () => {
  return src('public/**',{ base: 'public' })
  .pipe(dest('dist'))
}

// serve启动
const serve = () => {
  watch('src/assets/styles/*.scss', style)
  watch('src/assets/scripts/*.js', script)
  watch('src/*.html', page)
  // watch('src/assets/images/**', image)
  // watch('src/assets/fonts/**', font)
  // watch('public/**', extra)

  watch([
    'src/assets/images/**',
    'src/assets/fonts/**',
    'public/**',
  ],bs.reload)
  bs.init({
    notify: false, // 关闭提示
    port: 8080,
    open: true,
    // files:'dist/**',  // 监听变化【dist文件夹的所有文件夹的变化】
    server: {
      baseDir: ['temp','src','public'], // 开发阶段图片等访问src、public
      // 请求发生改变时，优先查看routes的配置,其次查看baseDir下的文件
      routes: {
        '/node_modules': 'node_modules'
      }
    }
  })
}

// 文件引用处理
const useref = () => {
  return src('temp/*.html',{ base: 'temp'})
  .pipe(plugins.useref({searchPath: ['temp','.']}))
  // 判断文件类型，执行转换流
  //.pipe(plugins.if(/\.js$/,plugins.uglify()))
  //.pipe(plugins.if(/\.css$/,plugins.cleanCss()))
  //.pipe(plugins.if(/\.html$/,plugins.htmlmin({
    //   collapseWhitespace: true,
    //   minifyCSS: true,  // 压缩内部的css
    //   minifyJS: true   // 压缩内部的js
    // })))  // 压缩属性中的空白字符
  .pipe(dest('dist'))
}

// 并行执行
const compile = parallel(style, script, page)
// 上线构建
const build = series(clean, parallel(series(useref, compile), image, extra)) // image, font
// 开发执行
const develop = series(compile,serve)

module.exports = {
  clean,
  build,
  develop,
}

